package com.simple.datax.intra.service.impl;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.simple.datax.SimpleFailMessage;
import com.simple.datax.SimpleMessage;
import com.simple.datax.SimpleResentMessage;
import com.simple.datax.api.MessageProcessor;
import com.simple.datax.service.DBResentLoaderService;
import com.simple.datax.service.ResentService;
import com.simple.datax.utils.MessageUtils;
import com.simple.datax.utils.SimpleConstants;

/**
 * @Title: ResentServiceImpl.java
 * @Package com.simple.datax.intra.service.impl
 * @Description: TODO(添加描述)
 * @author Paladin Chen
 * @date 2013-1-14 下午1:00:34
 * @version V1.0
 */
public class ResentServiceImpl implements ResentService {
	private static final Logger logger = LoggerFactory.getLogger(ResentServiceImpl.class);

	// 接下来的发送处理
	private MessageProcessor nextProcessor;

	private DBResentLoaderService resentLoader;

	private MessageProcessor failService;

	// 最大重发次数
	private int maxCount = 3;

	@Override
	public void resent(SimpleResentMessage srm) {
		try {
			SimpleMessage sm = resentLoader.getResentMsgContent(srm.getRecvRawMsgid(), srm.getState());

			if (sm == null) {
				logger.warn("Cannot find Recv_RAW_Msg of (" + srm.getRecvRawMsgid() + "), delete it!!!!");
				resentLoader.deleteProcing(srm.getRecvRawMsgid());
				return;
			}

			sm.setResendCount(srm.getResentCount());

			// 如果重发次数大于等于最大重发次数，则做发送失败处理,
			// 因为重发次数是在读出时进行计数，如果maxCount =
			// 3；则实际此处是第4次发送时起作用。防止parse处没有效果，导致一直重发
			// 既然可以重发，应该是报文正确，只是系统内部问题导致不能重发，故要生成正确的回执报文，因此，需要在parse后做异常处理。
			if (srm.getResentCount() >= maxCount) {
				resentLoader.deleteProcing(srm.getRecvRawMsgid());

				// 异常处理
				SimpleFailMessage sfm = MessageUtils.castFailMessage("Resend Count is larger than MAX.",
						SimpleConstants.ERROR_TYPE_RESEND, SimpleConstants.ERROR_LEVEL_CLASS, sm);

				// 注意这里需要处理SimpleFailMessage
				try {
					failService.process(sfm);
				} catch (Exception e) {
					logger.error(sm.toLog() + "Error Occur When Call " + failService.getClass().getName(), e);
				}
			} else {
				// 重发次数加1
				resentLoader.updateProcingCount(srm.getRecvRawMsgid(), (short) (srm.getResentCount() + 1));
				nextProcessor.process(sm);
			}
		} catch (Exception e) {
			logger.error("Error occur when resent SimpleResentMesssage(" + srm.getRecvRawMsgid() + "):", e);
		}
	}

	private boolean resent(String id, Short state) {
		try {
			SimpleMessage sm = resentLoader.getResentMsgContent(id, state);
			if (sm == null) {
				return false;
			}

			nextProcessor.process(sm);
			return true;
		} catch (Exception e) {
			logger.error("Error occur when resent message id(" + id + "):", e);
			return false;
		}
	}

	@Override
	public boolean resentws(String id) {
		return resent(id, SimpleConstants.STATUS_RESENT);
	}

	public MessageProcessor getNextProcessor() {
		return nextProcessor;
	}

	public void setNextProcessor(MessageProcessor nextProcessor) {
		this.nextProcessor = nextProcessor;
	}

	public DBResentLoaderService getResentLoader() {
		return resentLoader;
	}

	public void setResentLoader(DBResentLoaderService resentLoader) {
		this.resentLoader = resentLoader;
	}

	public MessageProcessor getFailService() {
		return failService;
	}

	public void setFailService(MessageProcessor failService) {
		this.failService = failService;
	}

	public int getMaxCount() {
		return maxCount;
	}

	public void setMaxCount(int maxCount) {
		this.maxCount = maxCount;
	}

}
